package com.jltx.xq.simplewatch.news.model.impl;

import com.jltx.xq.simplewatch.db.helper.NewsRecordDBHelper;
import com.jltx.xq.simplewatch.news.model.IWeChatLocalNewsModel;
import com.jltx.xq.simplewatch.news.model.IWeChatNetNewsModel;
import com.jltx.xq.simplewatch.news.model.IWeChatNewsModel;
import com.jltx.xq.simplewatch.news.model.bean.NewsRecord;
import com.jltx.xq.simplewatch.news.model.bean.WeChatNews;
import com.jltx.xq.simplewatch.utils.ListUtils;

import java.util.ArrayList;
import java.util.List;

import cn.jltx.utils.XqLog;
import io.reactivex.Observable;
import io.reactivex.annotations.NonNull;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Predicate;


/**
 * @author jltxseo
 *         Created by junlintianxia on 2017/08/25.
 */

public class WeChatNewsModelImpl implements IWeChatNewsModel,IWeChatLocalNewsModel,IWeChatNetNewsModel {

    public static final String TAG = "WeChatNewsModelImpl";

    private WeChatNewsLocalModelImpl weChatNewsLocalModel;
    private WeChatNewsNetModelImpl weChatNewsNetModel;

    public WeChatNewsModelImpl() {
        weChatNewsLocalModel = new WeChatNewsLocalModelImpl();
        weChatNewsNetModel = new WeChatNewsNetModelImpl();
    }

    @Override
    public Observable<List<WeChatNews>> getWeChatNews(String channel, int limitNum, boolean isDown) {
        Observable<List<WeChatNews>> observable = null;
        if (weChatNewsLocalModel.isHadCacheNewsRecord()) {  //判断是否页面第一次加载数据
            if (isDown) {  //下拉去网络获取新闻数据
                observable = getNetWeChatNews(channel, limitNum, isDown);
            } else {  //上拉加载数据库缓存的上一页的数据
                observable = getLocalWeChatNews(channel, limitNum, isDown);
            }
        } else {
            //concat()操作符持有多个Observable对象，并将它们按顺序串联成队列。 first()操作符只从串联队列中取出并发送第一个事件。
            //因此，如果使用concat().first()，无论多少个数据源，只有第一个事件会被检索出并发送
            //实现先去本地数据库取数据，取到数据就获取这第一个数据，如果取到本地数据库的数据是空的就去网络获取数据，
            // 网络还是获取不到数据时最后默认返回first里面的默认空List
            observable = getConcatLocalAndNetWeChatNews(channel,limitNum,isDown);
        }
        return observable;
    }

    /**
     * 获取数据库缓存的数据
     * @param channel
     * @param limitNum
     * @param isDown
     * @return
     */
    public Observable<List<WeChatNews>> getLocalWeChatNews(String channel, int limitNum, boolean isDown) {
        return weChatNewsLocalModel.getWeChatNews(channel, limitNum, isDown);
    }

    /**
     * 获取网络的数据
     * @param channel
     * @param limitNum
     * @param isDown
     * @return
     */
    public Observable<List<WeChatNews>> getNetWeChatNews(String channel, int limitNum,boolean isDown) {
        return weChatNewsNetModel.getWeChatNews(channel, limitNum, isDown)
                .doOnNext(new Consumer<List<WeChatNews>>() {
                    @Override
                    public void accept(@NonNull List<WeChatNews> weChatNewsList) throws Exception {
                        XqLog.d(TAG,"保存网络新闻数据"+Thread.currentThread());
                        int lastMaxPage = 0;
                        if(!weChatNewsNetModel.isHadCacheNewsRecord()){
                            weChatNewsNetModel.setLastMaxPageNewsRecord(0);
                            NewsRecord newsRecord = NewsRecordDBHelper.getLastNewsRecord(channel); //根据频道名获取上一次page为最大页面的新闻数据
                            if(newsRecord != null && newsRecord.getPage() > 0){
                                lastMaxPage = newsRecord.getPage();
                                XqLog.d(TAG,"同步最大的页码到NetModel=>"+newsRecord.getPage());
                                weChatNewsNetModel.setLastMaxPageNewsRecord(newsRecord.getPage());
                            }
                        }else {
                            lastMaxPage = weChatNewsNetModel.getLastMaxPageNewsRecord();
                        }
                        if(!ListUtils.isEmpty(weChatNewsList)){
                            XqLog.d(TAG,"新闻页码增加到"+(lastMaxPage + 1));
                            weChatNewsNetModel.setLastMaxPageNewsRecord(lastMaxPage + 1);
                            saveWeChatNews(channel,lastMaxPage + 1,weChatNewsList);
                        }else {
                            XqLog.d(TAG,"从网络获取不到新的新闻");
                        }

                    }
                });
    }

    /**
     * 优先到数据库取新闻数据，取不到再去网络取数据
     * @param channel
     * @param limitNum
     * @param isDown
     * @return
     */
    public Observable<List<WeChatNews>> getConcatLocalAndNetWeChatNews(String channel, int limitNum, boolean isDown){

        //concat()操作符持有多个Observable对象，并将它们按顺序串联成队列。 first()操作符只从串联队列中取出并发送第一个事件。
        //因此，如果使用concat().first()，无论多少个数据源，只有第一个事件会被检索出并发送
        //实现先去本地数据库取数据，取到数据就获取这第一个数据，如果取到本地数据库的数据是空的就去网络获取数据，
        // 网络还是获取不到数据时最后默认返回first里面的默认空List
        return Observable.concat(getLocalWeChatNews(channel,limitNum,isDown),getNetWeChatNews(channel, limitNum, isDown))
                .filter(new Predicate<List<WeChatNews>>() {
                    @Override
                    public boolean test(@NonNull List<WeChatNews> weChatNewsList) throws Exception {
                        return !ListUtils.isEmpty(weChatNewsList);
                    }
                })
                .first(new ArrayList<WeChatNews>())
                .toObservable()
                .doOnNext(new Consumer<List<WeChatNews>>() {
                    @Override
                    public void accept(@NonNull List<WeChatNews> weChatNewsList) throws Exception {
                        XqLog.d(TAG,"策略后得到的新闻数据"+Thread.currentThread());
                        if(!weChatNewsNetModel.isHadCacheNewsRecord()){
                            weChatNewsNetModel.setLastMaxPageNewsRecord(0);
                            NewsRecord newsRecord = NewsRecordDBHelper.getLastNewsRecord(channel); //根据频道名获取上一次page为最大页面的新闻数据
                            if(newsRecord != null && newsRecord.getPage() > 0){
                                XqLog.d(TAG,"同步最大的页码到NetModel=>"+newsRecord.getPage());
                                weChatNewsNetModel.setLastMaxPageNewsRecord(newsRecord.getPage());
                            }
                        }
                    }
                });
    }
    @Override
    public  void saveWeChatNews(String channel, int page, List<WeChatNews> newsList) {
         weChatNewsNetModel.saveWeChatNews(channel,page,newsList);
    }

    @Override
    public boolean isHadCacheNewsRecord() {
        return weChatNewsLocalModel.isHadCacheNewsRecord() || weChatNewsNetModel.isHadCacheNewsRecord();
    }

    @Override
    public Integer getLastNewsRecordPage() {
        return weChatNewsLocalModel.getLastNewsRecordPage();
    }
}
